package com.zd.springcloud.tx;

import com.mysql.cj.jdbc.MysqlXADataSource;
import com.mysql.cj.jdbc.MysqlXid;

import javax.sql.XAConnection;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.DriverManager;

/**
 * 分布式事务产生的根本原因是数据库连接用的不是同一个
 *
 * 解决方式
 *  XA最基础的方式解决分布式事务，强一致性。事务没有提交前，数据还是原来的数据，没有变化。
 *
 *  强一致性的XA模式基于CP的模式
 */
public class FenBuShiShiWu {
    public static void main(String[] args) throws Exception{
        String url = "jdbc:mysql://47.101.218.65:3306/aaa?serverTimezone=UTC&useSSL=false";
        String url1 = "jdbc:mysql://47.101.218.65:3307/aaa?serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "root";


        MysqlXADataSource aaaDataSource = new MysqlXADataSource();
        aaaDataSource.setUrl(url);
        aaaDataSource.setUser(username);
        aaaDataSource.setPassword(password);

        MysqlXADataSource bbbDataSource = new MysqlXADataSource();
        bbbDataSource.setUrl(url1);
        bbbDataSource.setUser(username);
        bbbDataSource.setPassword(password);

        //获取资源管理器
        XAConnection aaaConn = aaaDataSource.getXAConnection();
        XAResource aaaResource = aaaConn.getXAResource();  //aaa的资源管理器


        XAConnection bbbConn = bbbDataSource.getXAConnection();
        XAResource bbbResource = bbbConn.getXAResource();  //bbb的资源管理器


        Xid aaaId = new MysqlXid("aaa".getBytes(),"bbb".getBytes(),1);
        Xid bbbId = new MysqlXid("www".getBytes(),"ppp".getBytes(),1);

        try{
            /**
             * 事务管理器通知给王五减钱，给赵六加钱，通知两个RM做update操作
             * 1、update操作前要有 开启xa事务
             */

            //1、王五开启XA
            aaaResource.start(aaaId,XAResource.TMNOFLAGS);

            // 王五减钱
            String sql = "update user set money = money - 60 where id = 1";
            aaaConn.getConnection().prepareStatement(sql).execute();
            //执行完告诉TM执行成功，第二个参数标识
            aaaResource.end(aaaId,XAResource.TMSUCCESS);




            //1、赵六开启XA
            bbbResource.start(bbbId,XAResource.TMNOFLAGS);
            // 赵六加钱
            String sql1 = "update user set money = money + 60 where id =1";
            bbbConn.getConnection().prepareStatement(sql1).execute();
            //执行完告诉TM执行成功，第二个参数标识
            bbbResource.end(bbbId,XAResource.TMSUCCESS);

            //int i = 10 / 0;

            //准备
            int prepare = aaaResource.prepare(aaaId);
            int prepare1 = bbbResource.prepare(bbbId);

            //两个都是成功的才算成功,才提交
            if(prepare == XAResource.XA_OK && prepare1 == XAResource.XA_OK){
                aaaResource.commit(aaaId,false);
                bbbResource.commit(bbbId,false);
            }else{
                aaaResource.rollback(aaaId);
                bbbResource.rollback(bbbId);
            }
        }catch (Exception e){
            System.out.println("出现了异常");
            aaaResource.rollback(aaaId);
            bbbResource.rollback(bbbId);
        }finally {
            bbbConn.close();
            aaaConn.close();
        }









    }
}
